package cn.tradewin.pmp.services.mail;

import java.io.StringWriter;
import java.util.Date;

import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

import freemarker.template.Configuration;
import freemarker.template.Template;

public class MailServiceImpl implements MailService {

	private final Session mailSession;
	
	private final Configuration freeMarker;
	
	public MailServiceImpl(final Session session, Configuration freeMarker) {
		this.mailSession = session;
		this.freeMarker = freeMarker;
	}
	
	public final void sendMail(MailMetaData metaData) throws MailException {
		if (metaData == null) {
			throw new MailException("Mail MetaData is null");
		}
		String from = metaData.getFrom();
		if (from == null) {
			from = mailSession.getProperty("mail.from");
		}
		try {
			MimeMessage message = new MimeMessage(mailSession);
			message.setSentDate(new Date());
			// From Mail Address
			message.setFrom(new InternetAddress(from));
			// To Mail Address
			if (metaData.getTo() == null) {
				throw new MailException("please specified the mail to user");
			}
			message.setRecipients(Message.RecipientType.TO,
					buildAddress(metaData.getTo()));
			// cc Mail Address
			if (metaData.getCc() != null) {
				message.setRecipients(Message.RecipientType.CC,
						buildAddress(metaData.getCc()));
			}
			// bcc Mail Address
			if (metaData.getBcc() != null) {
				message.setRecipients(Message.RecipientType.BCC,
						buildAddress(metaData.getBcc()));
			}
			// set subject of the mail
			message.setSubject(metaData.getSubject(), "UTF-8");
			String str = fillContent(metaData);
			message.setText(str, "UTF-8");
			message.saveChanges();
			
//			mailSession.setDebug(true);
			
			// send message
			Transport transport = mailSession.getTransport("smtp");
	        transport.connect();
	        transport.sendMessage(message, message.getAllRecipients());
	        transport.close();
		} catch (Exception e) {
			throw new MailException("", e);
		}
	}
	
	/**
	 * construct the MailAddress object
	 * @param address
	 * @return
	 * @throws AddressException
	 */
	private final InternetAddress[] buildAddress(String[] address)
			throws AddressException {
		if (address == null) {
			return null;
		}
		InternetAddress[] add = new InternetAddress[address.length];
		for (int i = 0; i < address.length; i++) {
			add[i] = new InternetAddress(address[i]);
		}
		return add;
	}
	
	/**
	 * fill the content of the mail by specified meta info
	 * 
	 * @param metaData
	 * @return formated mail content
	 * @throws Exception 
	 */
	private final String fillContent(MailMetaData metaData) throws Exception {
		String fml = "templates/mail/" + metaData.getVmcd();
		Template template = freeMarker.getTemplate(fml);
		StringWriter content = new StringWriter();
		template.process(metaData.getContent(), content);
		return content.toString();
	}
}
